<?php

namespace Pay\Controller;

use Common\Common\Api\Redis;
use Common\Common\Api\Redis\Channel;
use Common\Common\Api\Redis\Member;
use Common\Common\Api\Redis\MemberGroup;
use Common\Common\Api\Redis\Product;
use Think\Controller;

class PayController extends Controller{
    //商家信息
    public $merchants;
    //网站地址
    public $_site;
    //通道信息
    public $channel;
    //商户支付REDIS KEY
    private $order_pay_ips = "order_pay_ips";
    protected $son_class;

    public function __construct(){
        parent::__construct();
        //$this->_site = ((is_https()) ? 'https' : 'http') . '://' . C("DOMAIN") . '/';
        $this->_site = ((is_https()) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . '/';

        $ip = getIP();
        $arr = C("IP") ? C("IP") : [];
        if(in_array($ip,$arr)){
            $this->showip();
        }

        $classes = explode("\\",get_called_class());
        $class = end($classes);
        $this->son_class = htmlspecialchars(substr($class, 0, stripos($class, "Controller")));

        $this->assign("os", GetOs());
        $this->assign("is_mobile", isMobile() ? 1:0);
    }

    //回调
    protected function checkOrderNotify($orderid){
        $orderid = htmlspecialchars($orderid);

        $find = M("Order")->where(array("pay_orderid"=>$orderid,'pay_tongdao'=>$this->son_class))->find();

        if(!$find){
            exit("order_not_found1");
        }

        if(!$find['allowback']){
            exit("order_cannot_callback_by_admin");
        }

        $channel = Channel::getInstance()->find(['code'=>$this->son_class]);
        if(!$channel){
            $channel = M("Channel")->where(['code'=>$this->son_class])->find();
        }

        $huijin = ['Huijin','Huijinweixin'];
        if(in_array($this->son_class, $huijin)){
            $flag = true;
        }else{
            $flag = false;
        }

        if(!$channel){
            if($flag){
                exit(json_encode(['code'=>0,'msg'=>"成功"]));
            }

            if($this->son_class == 'Dongfang2'){
                exit("STATUS:MIUPAYOK");
            }

            if($this->son_class == 'Xiaoshu'){
                exit("success");
            }

            exit("channel_not_found");
        }

        if(!$channel['allownotify']){
            if($flag){
                exit(json_encode(['code'=>0,'msg'=>"成功"]));
            }

            if($this->son_class == 'Dongfang2'){
                exit("STATUS:MIUPAYOK");
            }

            if($this->son_class == 'Xiaoshu'){
                exit("success");
            }

            exit("deny");
        }

        if(!$find){
            if($flag){
                exit(json_encode(['code'=>0,'msg'=>"成功"]));
            }

            if($this->son_class == 'Dongfang2'){
                exit("STATUS:MIUPAYOK");
            }

            if($this->son_class == 'Xiaoshu'){
                exit("success");
            }

            exit("order_not_fonund");
        }

        $time = time() - 15 * 60;
        if($find['pay_applydate'] < $time){
            if($flag){
                exit(json_encode(['code'=>0,'msg'=>"成功"]));
            }

            if($this->son_class == 'Dongfang2'){
                exit("STATUS:MIUPAYOK");
            }

            if($this->son_class == 'Xiaoshu'){
                exit("success");
            }

            exit("order_has_overtime");
        }

        return $find;
    }

    //补发
    protected function checkOrderNotify2($orderid, $tongdao){
        $orderid = htmlspecialchars($orderid);
        $tongdao = htmlspecialchars($tongdao);

        $find = M("Order")->where(array("pay_orderid"=>$orderid,'pay_tongdao'=>$tongdao))->find();

        if(!$find['allowback']){
            exit("order_cannot_callback_by_admin");
        }

        $channel = Channel::getInstance()->find(['code'=>$find['pay_tongdao']]);

        if(!$channel){
            exit("channel_not_found");
        }

        if(!$channel['allownotify']){
            exit("deny");
        }

        if(!$find){
            exit("order_not_fonund");
        }

        $time = time() - 5 * 3600 * 24;
        //$time = time() - 10 * 60;
        if($find['pay_applydate'] < $time){
            exit("order_has_overtime");
        }

        return $find;
    }

    //盈联的IP
    protected function yinglianip(){
        return ["47.244.39.61"];
    }

    public function showip(){
        $this->showmessage("您因为刷单，封禁一天");
        exit;
    }

    /**
     * 创建订单
     * @param $parameter
     * @return array
     */
    protected function orderadd($parameter){
        //通道信息
        $this->channel = $parameter['channel'];
        //用户信息
        $this->merchants = Member::getInstance()->getById($this->channel['userid']);
        if(!$this->merchants){
            $this->merchants = M("Member")->where(['id'=>$this->channel['userid']])->find();
        }

        $group = MemberGroup::getInstance()->getById($this->merchants['gid']);
        if(!$group){
            $group = M("MemberGroup")->where(['id'=>$this->merchants['gid']])->find();
        }

        $groupname = $group ? $group['name'] : '未知分组';

        $return = array();
        // 通道名称
        $PayName = htmlspecialchars($parameter["code"]);
        // 交易金额比例
        $moneyratio = $parameter["exchange"];
        //商户编号
        $return["memberid"] = $userid = shanghubianhao($this->merchants['id']);

        //银行通道费率
        $syschannel = Channel::getInstance()->getById($this->channel['api']);
        if(!$syschannel){
            $syschannel = M("Channel")->where(['id'=>$this->channel['api']])->find();
        }

        //平台通道 
        $platform = Product::getInstance()->getById($this->channel['pid']);
        if(!$platform){
            $platform = M("Product")->where(['id'=>$this->channel['pid']])->find();
        }

        $user=$this->merchants;

        //是否指定通道
        //if(!empty($user['td_id'])){
        //$syschannel["signkey"]=$user['td_code'];
        //$syschannel["mch_id"]=$user['td_merid'];
        //}

        //回调参数
        $return = [
            "mch_id" => $syschannel["mch_id"], //商户号
            "signkey" => $syschannel["signkey"], // 签名密钥
            "appid" => $syschannel["appid"], // APPID
            "appsecret" => $syschannel["appsecret"], // APPSECRET
            "gateway" => $syschannel["gateway"] ? $syschannel["gateway"] : $parameter["gateway"], // 网关
            "notifyurl" => "http://callback.wanglianfu.com/Pay_" . $PayName . "_notifyurl.html",
            "callbackurl" => "http://callback.wanglianfu.com/Pay_" . $PayName . "_callbackurl.html",
            'unlockdomain' => $syschannel['unlockdomian'] ? $syschannel['unlockdomian'] : '', //防封域名
            'codeName' => $platform['code']
        ];

        //商户的费率
        //获取实际支付通道id
        if($syschannel['rate1'] > 0){
            $feilv = $syschannel['rate1'];
        }elseif(in_array($syschannel['paytype'],[3,4,17,18, 21,22,23,24])){
            $_paytype = $syschannel['paytype'];
            $_map = [
                3 => 101,
                4 => 104,
                17 => 93,
                18 => 94,
                21 => 90,
                22 => 89,
                23 => 88,
                24 => 87,
            ];
            $feilv = getUserRate($this->channel['userid'], $_map[$_paytype], $user);
        }else{
            //商户的费率
            $feilv = getUserRate($this->channel['userid'], $this->channel['pid'], $user);
        }
		
		if(!$feilv || $feilv == 0){
			$this->showmessage('系统费率异常!');
		}

        //我们给代理商的费率
        if($this->merchants['parentid'] >1){
            $feilv_ag = getUserRate($this->merchants['parentid'], $this->channel['pid']);
        }else{
            $feilv_ag = 0;
        }

        //金额格式化
        $pay_amount = I("request.pay_amount", 0,"floatval");

        $return["amount"] = floatval($pay_amount) * $moneyratio; // 交易金额
        $pay_sxfamount = $pay_amount * $feilv; // 手续费
        $pay_shijiamount = number_format($pay_amount - $pay_sxfamount,3,'.',''); // 实际到账金额

        //商户订单号(用户生成)
        $out_trade_id = htmlspecialchars($parameter['out_trade_id']);
        //生成系统订单号(系统生成)
        $pay_orderid = $parameter['orderid'] ? $parameter['orderid'] : get_requestord();

        $Order = M("Order");
		if($Order->where(array("pay_orderid"=>$pay_orderid))->find()){
			$this->showmessage('订单号已经存在！');
		}

        if ($code=$this->verify()) {
            $return["bankcode"] = $this->channel['pid'];
            $return["orderid"] = $pay_orderid; // 系统订单号
            $return["out_trade_id"] = $out_trade_id; // 外部订单号
            $return["subject"] = $parameter['body']; // 商品标题
			
            $data["pay_memberid"] = $userid;
            $data["pay_orderid"] = $pay_orderid;
            $data["pay_amount"] = $pay_amount; // 交易金额
            $data["pay_poundage"] = $pay_sxfamount; // 手续费
            $data["pay_actualamount"] = $pay_shijiamount; // 到账金额
            $data["pay_applydate"] = time();
            $data["pay_bankcode"] = $this->channel['pid'];
            $data["pay_bankname"] = htmlspecialchars($platform['name']);
            $data["pay_notifyurl"] = htmlspecialchars(I("request.pay_notifyurl"));
            $data["pay_callbackurl"] = htmlspecialchars(I("request.pay_callbackurl"));
            $data["pay_status"] = 0;
            $data["pay_tongdao"] = htmlspecialchars($syschannel['code']);
            $data["pay_zh_tongdao"] = htmlspecialchars($syschannel['title']);
            $data["pay_ytongdao"] = htmlspecialchars($parameter["code"]);
            $data["pay_yzh_tongdao"] = htmlspecialchars($parameter["title"]);
            $data["pay_tjurl"] = htmlspecialchars($_SERVER["HTTP_REFERER"]);
            $data["pay_productname"] = htmlspecialchars(I("request.pay_productname"));
            $data["pay_productnum"] = htmlspecialchars(I("request.pay_productnum"));
            $data["pay_productdesc"] = htmlspecialchars(I("request.pay_productdesc"));
            $data["pay_producturl"] = htmlspecialchars(I("request.pay_producturl"));
            $data["attach"] = htmlspecialchars(I("request.pay_attach"));
            $data["out_trade_id"] = $out_trade_id;
            $data["ddlx"] = I("post.ddlx", 0,'intval');
            $data["memberid"] = htmlspecialchars($return["mch_id"]);
            $data["key"] = htmlspecialchars($return["signkey"]);
            $data["account"] = htmlspecialchars($return["appid"]);
            $data['rd_rate'] = $syschannel['rate'];
            $data['rd_money'] = $pay_amount * $syschannel['rate'];
            $data['os'] = htmlspecialchars(GetOs());
            $data['groupname'] = htmlspecialchars($groupname);

            if($this->merchants['parentid']>1){
                //代理商费率差
                $data['ag_rate'] = $feilv;
                $data['ag_money'] = $pay_amount * ($feilv - $feilv_ag);
            }else{
                $data['ag_rate'] = 0;
                $data['ag_money'] = 0;
            }

            if($this->merchants['parentid']>1){
                $data['us_rate'] = $feilv_ag;
            }else{
                $data['us_rate'] = $feilv;
            }
            $data['us_money'] = $data['pay_poundage'] - $data['rd_money'] - $data['ag_money'];

            if($data['us_money'] <= 0){
                $this->showmessage('系统费率异常，请联系管理员!');
            }

            $data['ip'] = htmlspecialchars(getIP());
            $data['channel_id'] = $this->channel['api'];
            $data['is_mobile'] = isMobile() ? 1 : 0;
            $data['parentid'] = $user['parentid'];

            if(function_exists("geoip_record_by_name")){
                $ip_info = geoip_record_by_name(getIP());
                if($ip_info && !empty($ip_info)){
                    $data['country'] = htmlspecialchars($ip_info['country_name']);
                    $data['city'] = htmlspecialchars($ip_info['city']);
                    $data['latitude'] = htmlspecialchars($ip_info['latitude']);
                    $data['longitude'] = htmlspecialchars($ip_info['longitude']);
                }
            }

            $oid = $Order->add($data);
            if ($oid) {
                $return['datetime'] = date('Y-m-d H:i:s', $data['pay_applydate']);
                $return["status"] = "success";
                $return['out_trade_id'] = htmlspecialchars($out_trade_id);
                return $return;
            } else {
                $this->showmessage('系统错误');
            }
        } else {
            $this->showmessage('签名验证失败',$code);
        }
    }

    public function getip(){
        $ip = I("get.ip",'','htmlspecialchars');

        $data = [];

        if($ip){
            if(function_exists("geoip_record_by_name")){
                $ip_info = geoip_record_by_name($ip);
                if($ip_info && !empty($ip_info)){
                    $data['country'] = $ip_info['country_name'];
                    $data['city'] = $ip_info['city'];
                    $data['latitude'] = $ip_info['latitude'];
                    $data['longitude'] = $ip_info['longitude'];
                }
            }
        }

        echo json_encode($data);
    }

    /**
     * 回调处理订单
     * @param $TransID
     * @param $PayName
     * @param int $returntype
     */
    protected function EditMoney($TransID, $PayName='', $returntype = 0){
        $PayName='';

        $Order = M("Order");
        $list = $Order->where(['pay_orderid'=>$TransID])->find();
        $today = date("Y-m-d",time());

        if(!$list){
            return false;
        }
        $product = Product::getInstance()->find(['name'=>$list['pay_bankname']]);
        if(!$product){
            $product = M("Product")->where(['name'=>$list['pay_bankname']])->find();
        }

        $channel = Channel::getInstance()->find(['title'=>$list['pay_yzh_tongdao']]);
        if(!$channel){
            $channel = M("Channel")->where(['title'=>$list['pay_yzh_tongdao']])->find();
        }

        //用户ID
        $userid = getIdByBianHao($list["pay_memberid"]); // 商户ID
        if ( intval($list["pay_status"]) === 0) {
            //更新订单状态 1 已成功未返回 2 已成功已返回
            $Model = M();
            $Model->startTrans();
            $flag = true;
            $r = $Order->where(['pay_orderid' => $TransID])->save(['pay_status' => 1]);

            $flag = $flag && $r;
            if(!$r){
                $Model->rollback();
                return false;
            }
            $r = $Order->where(['pay_orderid' => $TransID])->save(['pay_successdate' => time()]);
            if(!$r){
                $Model->rollback();
                return false;
            }
            $flag = $flag && $r;

            if($flag){
                $Model->commit();
            }else{
                $Model->rollback();
                return false;
            }

            $date = date("Y-m-d",time());
            $apirun = M("Apirun")->where(array("channel_id"=>$list['channel_id'],"date"=>$date))->find();
            if(!$apirun){
                M("Apirun")->add(array("channel_id"=>$list['channel_id'],"code"=>$list['pay_tongdao'],"money"=>$list['pay_amount'],"date"=>date("Y-m-d",time())));
            }else{
                M("Apirun")->where(array("channel_id"=>$list['channel_id'],"date"=>$date))->save(array(
                    "money" => array("exp","money+{$list['pay_amount']}"),
                ));
            }

            //通道余额
            $tongji_balance = M("TongdaoBalance");
            $name = getTongdaoNameShort($list['pay_zh_tongdao']);
            if(!$tongji_balance->where(["tongdao"=>$name])->find()){
                $tongji_balance->add([
                    'tongdao' => $name,
                    'total' => $list['pay_amount'],
                    'balance' => $list['pay_amount'] - $list['rd_money'],
                ]);
            }else{
                $tongji_balance->where(["tongdao"=>$name])->save([
                    'total' => ['exp',"total+{$list['pay_amount']}"],
                    'balance' => ['exp',"balance+{$list['pay_amount']}-{$list['rd_money']}"],
                ]);
            }

            //商户
            $member = M('Member')->where(['id'=>$userid])->find();

            if($product && $product['type']){
                $t_days = intval($product['type']);
                //T+1结算
                M('Member')->where(['id'=>$userid])->save([
                    'blockedbalance'=>array('exp',"blockedbalance+{$list['pay_actualamount']}"),
                    'total'=>array('exp',"total+{$list['pay_actualamount']}"),
                ]);

                if(M('Blockedlog')->where(['userid'=>$member['id'],'status'=>0,'createtime'=>$today])->find()){
                    $save = array();
                    $save['amount'] = ['exp',"amount+{$list['pay_actualamount']}"];
                    M("Blockedlog")->where(['userid'=>$member['id'],'status'=>0,'createtime'=>$today])->save($save);
                }else{
                    $rows = [
                        'userid'=>$userid,
                        'amount'=>$list['pay_actualamount'],
                        'thawtime'=> date("Y-m-d", strtotime("+{$t_days} day")),
                        'pid'=>$list['pay_bankcode'],
                        'createtime'=> $today,
                        'status'=>0
                    ];

                    M('Blockedlog')->add($rows);
                }

            }elseif($channel && $channel['type']){
                $t_days = intval($channel['type']);
                //T+1结算
                M('Member')->where(['id'=>$userid])->save([
                    'blockedbalance'=>array('exp',"blockedbalance+{$list['pay_actualamount']}"),
                    'total'=>array('exp',"total+{$list['pay_actualamount']}"),
                ]);

                if(M('Blockedlog')->where(['userid'=>$member['id'],'status'=>0,'createtime'=>$today])->find()){
                    $save = array();
                    $save['amount'] = ['exp',"amount+{$list['pay_actualamount']}"];
                    M("Blockedlog")->where(['userid'=>$member['id'],'status'=>0,'createtime'=>$today])->save($save);
                }else{
                    $rows = [
                        'userid'=>$userid,
                        'amount'=>$list['pay_actualamount'],
                        'thawtime'=> date("Y-m-d", strtotime("+{$t_days} day")),
                        'pid'=>$list['pay_bankcode'],
                        'createtime'=> $today,
                        'status'=>0
                    ];

                    M('Blockedlog')->add($rows);
                }
            }else{
                //T+0结算
                M('Member')->where(['id'=>$userid])->save([
                    'balance'=>array('exp', "balance+{$list['pay_actualamount']}"),
                    'total'=>array('exp', "total+{$list['pay_actualamount']}"),
                ]);
            }

            // 商户充值金额变动
            $arrayField = array(
                "userid" => $userid,
                "money" => $list["pay_actualamount"],

                //mycode
                //原金额
                'ymoney' => $member['total'],
                //变动后金额
                'gmoney' => $member['total'] + $list['pay_actualamount'],
                //end mycode

                "datetime" => date("Y-m-d H:i:s", time()),
                "tongdao" => htmlspecialchars($list['pay_bankcode']),
                "transid" => $TransID,
                "orderid" => $list["out_trade_id"],
                'contentstr'=>$list['out_trade_id'].'订单充值',
                "lx" => 1
            );
            M("Moneychange")->add($arrayField);

            //ip金额
            $this->saveIPmoney($list['ip'], $list['pay_amount']);
        }

        $member = Member::getInstance()->getById($userid);
        if(!$member){
            $member = M("Member")->where(['id'=>$userid])->find();
        }

        $Md5key = $member['apikey'];
        $returnArray = array( // 返回字段
            "memberid" => $list["pay_memberid"], // 商户ID
            "orderid" => $list['out_trade_id'], // 订单号
            'transaction_id'=>$list["pay_orderid"], //支付流水号
            "amount" => $list["pay_amount"], // 交易金额
            "datetime" => date("Y-m-d H:i:s"), // 交易时间
            "returncode" => "00", // 交易状态
        );
        $sign = $this->createSign($Md5key, $returnArray);

        $returnArray["sign"] = $sign;
        $returnArray["attach"] = htmlspecialchars_decode($list["attach"]);

        if ($returntype == 1) {
            $this->setHtml($list["pay_callbackurl"], $returnArray);
        } elseif ($returntype == 0) {
            $notifystr = "";
            foreach ($returnArray as $key => $val) {
                $notifystr = $notifystr . $key . "=" . $val . "&";
            }
            $notifystr = substr($notifystr, 0, -1);

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_TIMEOUT, 20);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,20);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_URL, htmlspecialchars_decode($list["pay_notifyurl"]));
            curl_setopt($ch, CURLOPT_POSTFIELDS, $notifystr);
            $contents = curl_exec($ch);

            if(curl_errno($ch)){
                echo 'error:' . curl_error($ch). "; errno: ". curl_errno($ch);
            }else{
                var_dump($contents);
            }
            curl_close($ch);

            //保存返回数据
            $order_return_save = array();
            $order_return_save['oid'] = htmlspecialchars($list['id']);
            $order_return_save['pay_orderid'] = htmlspecialchars($list['pay_orderid']);
            $order_return_save['out_trade_id'] = htmlspecialchars($list['out_trade_id']);
            $order_return_save['pay_amount'] = $list['pay_amount'];
            $order_return_save['pay_poundage'] = $list['pay_poundage'];
            $order_return_save['pay_actualamount'] = $list['pay_actualamount'];
            $order_return_save['pay_applydate'] = date("Y-m-d H:i:s", $list['pay_applydate']);
            $order_return_save['pay_successdate'] = date("Y-m-d H:i:s", date("Y-m-d H:i:s",time()));
            $order_return_save['pay_bankcode'] = htmlspecialchars($list['pay_bankcode']);
            $order_return_save['pay_tongdao'] = htmlspecialchars($list['pay_tongdao']);
            $order_return_save['pay_zh_tongdao'] = htmlspecialchars($list['pay_zh_tongdao']);
            $order_return_save['date'] = date("Y-m-d H:i:s",time());
            $order_return_save['request'] = htmlspecialchars($notifystr);

            $c = preg_replace("/\s+/",'', $contents);
            $order_return_save['return'] = htmlspecialchars($c);

            M("OrderWatch")->add($order_return_save);

            if(strlen($contents) > 10){
                return false;
            }

            //处理返回数据
            if (strstr(strtolower($contents), "ok") !== false || strstr(strtolower($contents), "success") !== false) {
                //更新交易状态
                $Order = M("Order");
                $_orderwhere = array('id'=>$list['id']);

                $find = $Order->where($_orderwhere)->find();
                if($find['pay_status'] != 2){
                    $Order->where($_orderwhere)->setField("pay_status", 2);
                }
            }
        }else if($returntype == 2){
            return $returnArray;
        }
    }

    private function saveIPmoney($ip,$money){
        $ips = json_decode(Redis::getInstance()->get($this->order_pay_ips), true);

        if(!$ip){
            return false;
        }

        if($money < 1000){
            return false;
        }

        $now = date("Y-m-d",time());
        if(!$ips || empty($ips)){
            $ips = [
                'time' => date("Y-m-d", time()),
                'ips' => [
                    $ip => [
                        'money' => floatval($money),
                        'nums' => 1,
                        'status' => 1,
                    ]
                ],
            ];
        }else{
            if($now !== $ips['time']){
                $ips = [
                    'time' => date("Y-m-d", time()),
                    'ips' => [
                        $ip => [
                            'money' => floatval($money),
                            'nums' => 1,
                            'status' => 1,
                        ]
                    ],
                ];
            }else{
                if(array_key_exists($ip,$ips['ips'])){
                    $ips['ips'][$ip]['money'] += floatval($money);
                    $ips['ips'][$ip]['nums']++;
                }else{
                    $ips['ips'][$ip]['money'] = floatval($money);
                    $ips['ips'][$ip]['nums'] = 1;
                    $ips['ips'][$ip]['status'] = 1;
                }
            }
        }

        Redis::getInstance()->set($this->order_pay_ips, json_encode($ips));
    }

    // 支付签名
    protected function get_paysign($arraystr, $key){
        ksort($arraystr);
        $buff = "";
        foreach ($arraystr as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        $string = $buff . "&key=".$key;
        $string = md5($string);
        $sign = strtoupper($string);
        return $sign;
    }

    /**
     *  验证签名
     * @return bool
     */
    protected function verify(){
        //POST参数
        $requestarray = array(
            "pay_memberid" => I("request.pay_memberid", 0,'intval'),
            "pay_orderid" => I("request.pay_orderid", ""),
            "pay_amount" => I("request.pay_amount", ""),
            "pay_applydate" => I("request.pay_applydate", ""),
            "pay_bankcode" => I("request.pay_bankcode", ""),
            "pay_notifyurl" => I("request.pay_notifyurl", ""),
            "pay_callbackurl" => I("request.pay_callbackurl", "")
        );

        $md5key = $this->merchants["apikey"];
        $md5keysignstr = $this->createSign($md5key, $requestarray);
        $pay_md5sign = I("request.pay_md5sign");

        if ($pay_md5sign == $md5keysignstr) {
            return true;
        } else {
            return false;
        }
    }

    protected function setHtml($tjurl, $arraystr){
        $str = '<form id="Form1" name="Form1" method="post" action="' . $tjurl . '">';
        foreach ($arraystr as $key => $val) {
            $str .= '<input type="hidden" name="' . $key . '" value="' . $val . '">';
        }
        $str .= '</form>';
        $str .=  '<script>';
        $str .= 'document.Form1.submit();';
        $str .= '</script>';
        exit( $str);
    }

    /**
     * 获取验签密钥
     * @param $code
     * @param $mch_id
     * @return mixed
     */
    protected function getSignkey($code, $mch_id){
        $signkey = M("Channel")->where(["code"=>$code,"mch_id"=>$mch_id])->getField("signkey");
        return $signkey;
    }

    protected function getmd5keykey($PayName, $MemberID){
        $Payapi = M("Payapi");
        $payapiid = $Payapi->where("en_payname='" . $PayName . "'")->getField("id");
        $Payapiaccount = M("Payapiaccount");
        $key = $Payapiaccount->where("payapiid=" . $payapiid . " and sid = '" . $MemberID . "'")->getField("keykey");
        return $key;
    }

    /**
     * 资金变动记录
     * @param $arrayField
     * @return bool
     */
    protected function MoenyChange($arrayField){
        // 资金变动
        $Moneychange = M("Moneychange");
        foreach ($arrayField as $key => $val) {
            $data[$key] = $val;
        }
        $Moneychange->add($data);
        return true;
    }

    /**
     * 创建签名
     * @param $Md5key
     * @param $list
     * @return string
     */
    protected function createSign($Md5key, $list){
        ksort($list);
        $md5str = "";
        foreach ($list as $key => $val) {
            if(!empty($val)){
                $md5str = $md5str . $key . "=" . $val . "&";
            }
        }
        $sign = strtoupper(md5($md5str . "key=" . $Md5key));
        return $sign;
    }

    // 页面跳转返回
    public function callbackurl(){
        exit("");
    }

    //异步返回
    public function notifyurl(){
        exit("");
    }

    public function bufa(){
        header('Content-type:text/html;charset=utf-8');
        $TransID = I("get.TransID",'','htmlspecialchars');
        $PayName = I("get.tongdao",'','htmlspecialchars');
        $sign = I("get.sign",'','htmlspecialchars');

        if($sign !== bufasign($TransID)){
            exit("sign wrong");
        }

        //$find = M("Order")->where(['pay_orderid'=>$TransID])->find();
        $find = $this->checkOrderNotify2($TransID, $PayName);
        if(!$find){
            exit("wrong");
        }

        $user = session("admin_auth");

        if(!$user){
            $user = session("user_auth");
        }

        if(!$user){
            exit("wrong2");
        }

        $username = $user['username'];
        $username = $find['optor'] . "|" . $username;
        M("Order")->where(['pay_orderid'=>$TransID])->save(['optor'=>$username]);

        echo("订单号：" . $TransID  . "已补发服务器点对点通知，请稍后刷新查看结果！<a href='javascript:window.close();'>关闭</a>");
        $this->EditMoney($TransID, $PayName, 0);
    }

    /**
     * 扫码订单状态检查
     *
     */
    public function checkstatus(){
        //exit();
        $orderid = htmlspecialchars(I("post.orderid"));
        $Order = M("Order");
        $order = $Order->where("pay_orderid='" . $orderid . "'")->find();
        if ($order['pay_status'] <> 0) {
            echo json_encode(array('status'=>'ok','callback'=>$this->_site."Pay_".$order['pay_tongdao']."_callbackurl.html?orderid="
                .$orderid."&pay_memberid=".$order['pay_memberid'].'&bankcode='.$order['pay_bankcode']));
            exit();
        } else {
            exit("no-$orderid");
        }
    }


    /**
     * 错误返回
     * @param string $msg
     * @param array $fields
     */
    protected function showmessage($msg='', $fields=array()){
        header('Content-Type:application/json; charset=utf-8');
        $data = array('status'=>'error', 'msg'=>$msg, 'data'=>$fields);
        echo json_encode($data,320);
        exit;
    }

    protected function showmessage_ok($fields=array()){
        header('Content-Type:application/json; charset=utf-8');
        $data = array('status'=>'success', 'msg'=>"获取数据成功", 'data'=>$fields);
        echo json_encode($data,320);
        exit;
    }


    /**
     * json返回
     * @param array $fields
     */
    protected function showJson($pc='', $web=''){
        header('Content-Type:application/json; charset=utf-8');
        $r = [];
        $r['pc_url'] = $pc;
        $r['wap_url'] = $web;

        $data = array('status'=>'success', 'msg'=>"", 'data'=>$r);
        echo json_encode($data,320);
        exit;
    }

    protected function isWangshangIp(){
        $ip = $_SERVER['REMOTE_ADDR'];
        if($ip != '47.93.255.149'){
            return false;
        }

        return true;
    }

    /**
     * 订单查询
     */
    public function queryOrder(){
        $orderid = htmlspecialchars(I("post.orderid"));
        $pay_memberid = I("post.pay_memberid",0,"intval");
        $sign = I("post.sign",'','htmlspecialchars');

        $ret = ['status'=>'10000','msg'=>''];

        if(!$orderid){
            $ret['status'] = '10001';
            $ret['msg'] = '商户订单号不能为空';

            $this->showmessage2($ret);
        }

        if(!$pay_memberid){
            $ret['status'] = '10002';
            $ret['msg'] = '商户号不能为空';

            $this->showmessage2($ret);
        }

        if(!$sign){
            $ret['status'] = '100003';
            $ret['msg'] = '签名不能为空';

            $this->showmessage2($ret);
        }

        $member = Member::getInstance()->getById(getIdByBianHao($pay_memberid));
        if(!$member){
            $ret['status'] = '10004';
            $ret['msg'] = '商户号不存在';

            $this->showmessage2($ret);
        }


        $str = "orderid={$orderid}&pay_memberid={$pay_memberid}&key={$member['apikey']}";
        $sign2 = strtoupper(md5($str));
        if($sign != $sign2){
            $ret['status'] = '10006';
            $ret['msg'] = '签名错误';

            $this->showmessage2($ret);
        }


        $m = M("Order");
        $order = $m->where("pay_memberid={$pay_memberid} AND out_trade_id='" . $orderid . "'")->find();
        if(!$order){
            $ret['status'] = '10007';
            $ret['msg'] = '订单号不存在';

            $this->showmessage2($ret);
        }

        if ($order['pay_status'] > 0) {
            $ret['msg'] = '支付成功';
            $this->showmessage2($ret);
        } else {
            $ret['status'] = '10005';
            $ret['msg'] = '未支付';

            $this->showmessage2($ret);
        }
    }

    protected function showmessage2($data){
        header('Content-Type:application/json; charset=utf-8');
        echo json_encode($data,320);
        exit;
    }

    //异步回调
    protected function async($orderid, $return){
        $arr = explode("\\", static::class);
        $class = end($arr);
        $class = substr($class, 0, strpos($class, 'Controller'));

        //保存所有回调
        if(!in_array(strtolower($class), ['maikou'])){
            $this->debug_callbackall($orderid,1);
        }

        if(function_exists('fastcgi_finish_request')){
            echo $return;
            // 刷新buffer
            ob_flush();
            flush();
            // 断开浏览器连接
            fastcgi_finish_request();
            $this->EditMoney($orderid,'',0);
        }else{
            //处理支付
            $this->EditMoney($orderid,'',0);

            //回调成功
            echo $return;
        }
    }

    protected function debug_callbackall($orderid,$status=1){
        $m = M("CallbackAll");

        if($m->where(['sn'=>$orderid])->find()){
            $m->where(['sn'=>$orderid])->save(['status'=>$status]);
        }else{
            $add = $this->getCallbackData($status);
            $add['sn'] = $orderid;
            $m->add($add);
        }
    }

    protected function getCallbackData($status=1){
        $arr = explode("\\", static::class);
        $class = end($arr);
        $class = substr($class, 0, strpos($class, 'Controller'));

        $p = I("post.");
        $g = I("get.");
        $s = $_SERVER;
        $o = file_get_contents('php://input');

        return [
            'channel' => htmlspecialchars($class),
            'origin' => htmlspecialchars($o),
            'post' => htmlspecialchars(var_export($p,true)),
            'gets' => htmlspecialchars(var_export($g,true)),
            'server' => '',
            'time' => date("Y-m-d H:i:s",time()),
            'ip' => htmlspecialchars(getIP()),
            'status'=>$status,
        ];
    }

    //数据库调试
    protected function debug_callback(){
        $arr = explode("\\", static::class);
        $class = end($arr);
        $class = substr($class, 0, strpos($class, 'Controller'));

        $m = M("Callback");

        $p = I("post.");
        $g = I("get.");
        $s = $_SERVER;
        $o = file_get_contents('php://input');

        $m->add([
            'channel' => htmlspecialchars($class),
            'origin' => htmlspecialchars($o),
            'post' => htmlspecialchars(var_export($p,true)),
            'gets' => htmlspecialchars(var_export($g,true)),
            'server' => htmlspecialchars(var_export($s,true)),
            'time' => date("Y-m-d H:i:s",time()),
            'ip' => getIP(),
        ]);
    }

    protected function debug_aaa($data){
        if(is_array($data)){
            $data = var_export($data, true);
        }

        $m = M("Aaa");
        $m->add(['data'=>$data]);
    }
	
	protected function makeSign($data,$key_name='key', $ignore = ['sign'], $toupper=true, $ignore_null = true, $mode=1){
		ksort($data);
		$data[$key_name] = $this->config['signkey'];
		
		$str = "";
		foreach($data as $k=>$v){
			if(in_array($k, $ignore)){
				continue;
			}
			
			if($ignore_null){
				if($v === null || $v === ''){
					continue;
				}
			}
			
			switch($mode){
				case 1:
					$str .= "{$k}={$v}&";
				break;
				default:
					$str .= $v;
			}
		}
		
		switch($mode){
			case 1:
				$str = substr($str, 0, -1);
			break;
			default:
				
		}
		
		return $toupper ? strtoupper(md5($str)) : md5($str);
	}

	//检查ip
    protected function checkip($ip,$can=[]){
        if(!in_array($ip, $can)){
            if($this->son_class == 'Dongfang2'){
                exit("STATUS:MIUPAYOK");
            }

            return false;
        }

        return true;
    }
}